/**
 * LevelGenerator - 关卡生成器
 * 负责程序化生成游戏关卡，包括障碍物布局、难度递增和关卡主题
 */

import { Entity, EntityType } from './Entity'
// import type { Vector2D } from './GameEngine' // 暂时不需要

/**
 * 关卡主题枚举
 */
export enum LevelTheme {
  CITY = 'city',
  FOREST = 'forest',
  DESERT = 'desert',
  SNOW = 'snow',
  SPACE = 'space'
}

/**
 * 障碍物模式接口
 */
export interface ObstaclePattern {
  /** 模式名称 */
  name: string
  /** 障碍物配置数组 */
  obstacles: ObstacleConfig[]
  /** 模式长度（像素） */
  length: number
  /** 最小难度等级 */
  minDifficulty: number
  /** 权重（影响选择概率） */
  weight: number
}

/**
 * 障碍物配置接口
 */
export interface ObstacleConfig {
  /** 障碍物类型 */
  type: string
  /** 相对X位置 */
  x: number
  /** 相对Y位置 */
  y: number
  /** 宽度 */
  width: number
  /** 高度 */
  height: number
  /** 额外属性 */
  properties?: Record<string, any>
}

/**
 * 关卡块接口
 */
export interface LevelChunk {
  /** 起始X坐标 */
  startX: number
  /** 结束X坐标 */
  endX: number
  /** 障碍物列表 */
  obstacles: Entity[]
  /** 收集品列表 */
  collectibles: Entity[]
  /** 背景元素列表 */
  backgroundElements: Entity[]
  /** 主题 */
  theme: LevelTheme
  /** 难度等级 */
  difficulty: number
}

/**
 * 背景元素接口
 */
export interface BackgroundElement {
  /** 元素类型 */
  type: string
  /** X坐标 */
  x: number
  /** Y坐标 */
  y: number
  /** 宽度 */
  width: number
  /** 高度 */
  height: number
  /** 滚动速度倍数 */
  scrollSpeed: number
  /** 层级 */
  layer: number
}

/**
 * 关卡生成器选项接口
 */
export interface LevelGeneratorOptions {
  /** 屏幕宽度 */
  screenWidth: number
  /** 屏幕高度 */
  screenHeight: number
  /** 块长度 */
  chunkLength?: number
  /** 初始难度 */
  initialDifficulty?: number
  /** 难度递增率 */
  difficultyIncrement?: number
  /** 最大难度 */
  maxDifficulty?: number
}

/**
 * 关卡生成器类
 */
export class LevelGenerator {
  private screenWidth: number
  private screenHeight: number
  private chunkLength: number
  private currentDifficulty: number
  private difficultyIncrement: number
  private maxDifficulty: number
  private currentTheme: LevelTheme
  private distanceGenerated: number = 0
  private obstaclePatterns: ObstaclePattern[] = []

  constructor(options: LevelGeneratorOptions) {
    this.screenWidth = options.screenWidth
    this.screenHeight = options.screenHeight
    this.chunkLength = options.chunkLength || 800
    this.currentDifficulty = options.initialDifficulty || 1
    this.difficultyIncrement = options.difficultyIncrement || 0.1
    this.maxDifficulty = options.maxDifficulty || 10
    this.currentTheme = LevelTheme.CITY

    this.initializeObstaclePatterns()
  }

  /**
   * 初始化障碍物模式
   */
  private initializeObstaclePatterns(): void {
    // 简单单个障碍物模式
    this.obstaclePatterns.push({
      name: 'single_barrier',
      obstacles: [{
        type: 'barrier',
        x: 400,
        y: this.screenHeight - 100,
        width: 40,
        height: 80,
      }],
      length: 600,
      minDifficulty: 1,
      weight: 10
    })

    // 双重障碍物模式
    this.obstaclePatterns.push({
      name: 'double_barrier',
      obstacles: [
        {
          type: 'barrier',
          x: 300,
          y: this.screenHeight - 100,
          width: 40,
          height: 80,
        },
        {
          type: 'barrier',
          x: 500,
          y: this.screenHeight - 100,
          width: 40,
          height: 80,
        }
      ],
      length: 700,
      minDifficulty: 2,
      weight: 8
    })

    // 跳跃+滑铲组合模式
    this.obstaclePatterns.push({
      name: 'jump_slide_combo',
      obstacles: [
        {
          type: 'barrier',
          x: 200,
          y: this.screenHeight - 100,
          width: 40,
          height: 80,
        },
        {
          type: 'low_barrier',
          x: 450,
          y: this.screenHeight - 40,
          width: 60,
          height: 40,
        }
      ],
      length: 650,
      minDifficulty: 3,
      weight: 7
    })

    // 坑洞模式
    this.obstaclePatterns.push({
      name: 'pit',
      obstacles: [{
        type: 'pit',
        x: 350,
        y: this.screenHeight - 20,
        width: 100,
        height: 20,
      }],
      length: 550,
      minDifficulty: 2,
      weight: 6
    })

    // 移动障碍物模式
    this.obstaclePatterns.push({
      name: 'moving_obstacle',
      obstacles: [{
        type: 'moving_barrier',
        x: 400,
        y: this.screenHeight - 120,
        width: 40,
        height: 80,
        properties: {
          moveSpeed: 50,
          moveRange: 100
        }
      }],
      length: 700,
      minDifficulty: 4,
      weight: 5
    })

    // 复杂组合模式
    this.obstaclePatterns.push({
      name: 'complex_combo',
      obstacles: [
        {
          type: 'barrier',
          x: 200,
          y: this.screenHeight - 100,
          width: 40,
          height: 80,
        },
        {
          type: 'pit',
          x: 350,
          y: this.screenHeight - 20,
          width: 80,
          height: 20,
        },
        {
          type: 'low_barrier',
          x: 550,
          y: this.screenHeight - 40,
          width: 60,
          height: 40,
        }
      ],
      length: 800,
      minDifficulty: 5,
      weight: 4
    })
  }

  /**
   * 生成关卡块
   * @param startX 起始X坐标
   * @returns 生成的关卡块
   */
  generateChunk(startX: number): LevelChunk {
    const endX = startX + this.chunkLength
    
    // 选择障碍物模式
    const pattern = this.selectObstaclePattern()
    
    // 生成障碍物
    const obstacles = this.generateObstacles(startX, pattern)
    
    // 生成收集品
    const collectibles = this.generateCollectibles(startX, endX)
    
    // 生成背景元素
    const backgroundElements = this.generateBackgroundElements(startX, endX)
    
    // 更新生成距离
    this.distanceGenerated += this.chunkLength
    
    // 检查是否需要增加难度
    this.updateDifficulty()
    
    // 检查是否需要切换主题
    this.updateTheme()

    return {
      startX,
      endX,
      obstacles,
      collectibles,
      backgroundElements,
      theme: this.currentTheme,
      difficulty: this.currentDifficulty
    }
  }

  /**
   * 选择障碍物模式
   * @returns 选中的障碍物模式
   */
  private selectObstaclePattern(): ObstaclePattern {
    // 过滤符合当前难度的模式
    const availablePatterns = this.obstaclePatterns.filter(
      pattern => pattern.minDifficulty <= this.currentDifficulty
    )

    if (availablePatterns.length === 0) {
      return this.obstaclePatterns[0] // 返回最简单的模式
    }

    // 根据权重随机选择
    const totalWeight = availablePatterns.reduce((sum, pattern) => sum + pattern.weight, 0)
    let randomValue = Math.random() * totalWeight
    
    for (const pattern of availablePatterns) {
      randomValue -= pattern.weight
      if (randomValue <= 0) {
        return pattern
      }
    }

    return availablePatterns[availablePatterns.length - 1]
  }

  /**
   * 生成障碍物实体
   * @param startX 起始X坐标
   * @param pattern 障碍物模式
   * @returns 障碍物实体数组
   */
  private generateObstacles(startX: number, pattern: ObstaclePattern): Entity[] {
    const obstacles: Entity[] = []

    for (const config of pattern.obstacles) {
      // 创建基础障碍物实体（这里使用简单的实现，后续会被具体的障碍物类替换）
      const obstacle = new SimpleObstacle({
        x: startX + config.x,
        y: config.y,
        width: config.width,
        height: config.height,
        type: EntityType.OBSTACLE,
        obstacleType: config.type,
        properties: config.properties
      })

      obstacles.push(obstacle)
    }

    return obstacles
  }

  /**
   * 生成收集品
   * @param startX 起始X坐标
   * @param endX 结束X坐标
   * @returns 收集品实体数组
   */
  private generateCollectibles(startX: number, endX: number): Entity[] {
    const collectibles: Entity[] = []
    const chunkWidth = endX - startX

    // 根据难度调整收集品数量
    const collectibleCount = Math.max(1, Math.floor(this.currentDifficulty / 2))
    
    for (let i = 0; i < collectibleCount; i++) {
      const x = Math.min(
        startX + (chunkWidth / (collectibleCount + 1)) * (i + 1),
        this.screenWidth - 20 // 确保收集品不超出屏幕右边界
      )
      const y = this.screenHeight - 150 - Math.random() * 100

      const collectible = new SimpleCollectible({
        x,
        y,
        width: 20,
        height: 20,
        type: EntityType.COLLECTIBLE
      })

      collectibles.push(collectible)
    }

    return collectibles
  }

  /**
   * 生成背景元素
   * @param startX 起始X坐标
   * @param endX 结束X坐标
   * @returns 背景元素实体数组
   */
  private generateBackgroundElements(startX: number, endX: number): Entity[] {
    const backgroundElements: Entity[] = []
    const chunkWidth = endX - startX

    // 生成远景建筑物或装饰
    const elementCount = Math.floor(chunkWidth / 200) + 1
    
    for (let i = 0; i < elementCount; i++) {
      const x = startX + (chunkWidth / elementCount) * i + Math.random() * 100
      const height = 80 + Math.random() * 120
      const y = this.screenHeight - height

      const backgroundElement = new SimpleBackgroundElement({
        x,
        y,
        width: 60 + Math.random() * 40,
        height,
        type: EntityType.BACKGROUND
      })

      backgroundElements.push(backgroundElement)
    }

    return backgroundElements
  }

  /**
   * 更新难度
   */
  private updateDifficulty(): void {
    // 每生成一定距离增加难度
    const difficultyCheckpoint = 2000 // 每2000像素检查一次难度
    
    if (this.distanceGenerated % difficultyCheckpoint === 0) {
      this.currentDifficulty = Math.min(
        this.maxDifficulty,
        this.currentDifficulty + this.difficultyIncrement
      )
    }
  }

  /**
   * 更新主题
   */
  private updateTheme(): void {
    // 每生成一定距离可能切换主题
    const themeCheckpoint = 5000 // 每5000像素检查一次主题
    
    if (this.distanceGenerated % themeCheckpoint === 0 && Math.random() < 0.3) {
      const themes = Object.values(LevelTheme)
      const currentIndex = themes.indexOf(this.currentTheme)
      const newIndex = (currentIndex + 1) % themes.length
      this.currentTheme = themes[newIndex]
    }
  }

  /**
   * 增加难度
   */
  increaseDifficulty(): void {
    this.currentDifficulty = Math.min(
      this.maxDifficulty,
      this.currentDifficulty + this.difficultyIncrement
    )
  }

  /**
   * 获取随机障碍物配置
   * @returns 随机障碍物配置
   */
  getRandomObstacle(): ObstacleConfig {
    const pattern = this.selectObstaclePattern()
    const obstacles = pattern.obstacles
    const baseObstacle = obstacles[Math.floor(Math.random() * obstacles.length)]
    
    // 添加一些随机变化以确保配置的多样性
    return {
      ...baseObstacle,
      x: baseObstacle.x + (Math.random() - 0.5) * 100, // 位置变化
      width: baseObstacle.width + (Math.random() - 0.5) * 20, // 宽度变化
      height: baseObstacle.height + (Math.random() - 0.5) * 20 // 高度变化
    }
  }

  /**
   * 获取当前难度
   */
  getCurrentDifficulty(): number {
    return this.currentDifficulty
  }

  /**
   * 获取当前主题
   */
  getCurrentTheme(): LevelTheme {
    return this.currentTheme
  }

  /**
   * 设置主题
   */
  setTheme(theme: LevelTheme): void {
    this.currentTheme = theme
  }

  /**
   * 重置生成器
   */
  reset(): void {
    this.currentDifficulty = 1
    this.currentTheme = LevelTheme.CITY
    this.distanceGenerated = 0
  }

  /**
   * 获取生成统计信息
   */
  getStats(): {
    distanceGenerated: number
    currentDifficulty: number
    currentTheme: LevelTheme
    availablePatterns: number
  } {
    return {
      distanceGenerated: this.distanceGenerated,
      currentDifficulty: this.currentDifficulty,
      currentTheme: this.currentTheme,
      availablePatterns: this.obstaclePatterns.filter(
        pattern => pattern.minDifficulty <= this.currentDifficulty
      ).length
    }
  }
}

/**
 * 简单障碍物实体（临时实现）
 */
class SimpleObstacle extends Entity {
  private obstacleType: string
  private properties: Record<string, any>

  constructor(options: {
    x: number
    y: number
    width: number
    height: number
    type: EntityType
    obstacleType: string
    properties?: Record<string, any>
  }) {
    super(options)
    this.obstacleType = options.obstacleType
    this.properties = options.properties || {}
  }

  update(deltaTime: number): void {
    // 基础物理更新
    this.applyPhysics(deltaTime)

    // 移动障碍物的特殊逻辑
    if (this.obstacleType === 'moving_barrier' && this.properties.moveSpeed) {
      const moveSpeed = this.properties.moveSpeed
      const moveRange = this.properties.moveRange || 100
      
      // 简单的来回移动逻辑
      if (!this.properties.moveDirection) {
        this.properties.moveDirection = 1
        this.properties.originalY = this.y
      }

      this.y += moveSpeed * this.properties.moveDirection * (deltaTime / 1000)
      
      if (Math.abs(this.y - this.properties.originalY) > moveRange) {
        this.properties.moveDirection *= -1
      }
    }
  }

  getObstacleType(): string {
    return this.obstacleType
  }
}

/**
 * 简单收集品实体（临时实现）
 */
class SimpleCollectible extends Entity {
  constructor(options: {
    x: number
    y: number
    width: number
    height: number
    type: EntityType
  }) {
    super(options)
  }

  update(deltaTime: number): void {
    // 基础物理更新
    this.applyPhysics(deltaTime)
    
    // 简单的浮动动画
    this.y += Math.sin(Date.now() * 0.005) * 0.5
  }
}

/**
 * 简单背景元素实体（临时实现）
 */
class SimpleBackgroundElement extends Entity {
  constructor(options: {
    x: number
    y: number
    width: number
    height: number
    type: EntityType
  }) {
    super(options)
  }

  update(deltaTime: number): void {
    // 背景元素通常不需要更新逻辑
    this.applyPhysics(deltaTime)
  }

  protected getDefaultColor(): string {
    return '#CCCCCC' // 浅灰色背景
  }
}